<template>
    <div class="page">
        <h2 class="title">货主合同管理</h2>

        <!-- 搜索区（提交式） -->
        <div class="search">
            <div class="row">
                <label>合同标题：</label>
                <input v-model="inputFilters.contractTitle" placeholder="请输入合同标题" @keyup.enter="handleSearch" />

                <label>货主单位：</label>
                <input v-model="inputFilters.cargoOwnerUnit" placeholder="请输入货主单位" @keyup.enter="handleSearch" />

                <label>经办人：</label>
                <input v-model="inputFilters.handler" placeholder="请输入经办人" @keyup.enter="handleSearch" />
            </div>
            <div class="row">
                <label>签订时间：</label>
                <input type="date" v-model="inputFilters.signingStart" @keyup.enter="handleSearch" />
                <span> - </span>
                <input type="date" v-model="inputFilters.signingEnd" @keyup.enter="handleSearch" />

                <label>审批状态：</label>
                <select v-model="inputFilters.status">
                    <option value="">全部</option>
                    <option value="待提交">待提交</option>
                    <option value="已审核">已审核</option>
                    <option value="已拒绝">已拒绝</option>
                </select>

                <button class="btn primary" @click="handleSearch">查询</button>
                <button class="btn" @click="handleReset">重置</button>
            </div>
        </div>

        <div class="toolbar">
            <button class="btn primary" @click="handleCreate">新增</button>
            <button class="btn danger" :disabled="selectedIds.length === 0" @click="handleBatchDelete">删除</button>
        </div>

        <!-- 表格 -->
        <div class="table-wrapper">
            <table class="table">
                <thead>
                    <tr>
                        <th style="width: 36px"><input type="checkbox" :checked="allSelected" @change="toggleAll" />
                        </th>
                        <th>合同编号</th>
                        <th>合同标题</th>
                        <th>货主单位</th>
                        <th>货主负责人</th>
                        <th>线路</th>
                        <th>吨运价</th>
                        <th>包车条件吨位</th>
                        <th>包车金额</th>
                        <th>签订日期</th>
                        <th>经办人</th>
                        <th>创建时间</th>
                        <th>状态</th>
                        <th>审批人</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    <tr v-if="loading">
                        <td :colspan="15" style="text-align:center">加载中...</td>
                    </tr>
                    <tr v-else-if="rows.length === 0">
                        <td :colspan="15" style="text-align:center">暂无数据</td>
                    </tr>
                    <tr v-for="row in rows" :key="row.id">
                        <td><input type="checkbox" :checked="selectedIds.includes(row.id)"
                                @change="toggleOne(row.id)" /></td>
                        <td>{{ row.contractNumber || '-' }}</td>
                        <td>{{ row.contractTitle || '-' }}</td>
                        <td>{{ row.cargoOwnerUnit || '-' }}</td>
                        <td>{{ row.cargoOwnerContact || '-' }}</td>
                        <td>{{ row.route || '-' }}</td>
                        <td>{{ row.tonFreightRate }}</td>
                        <td>{{ row.charterConditionTonnage }}</td>
                        <td>{{ row.charterAmount }}</td>
                        <td>{{ row.signingDate }}</td>
                        <td>{{ row.handler || '-' }}</td>
                        <td>{{ row.createdAt }}</td>
                        <td>{{ row.status || '-' }}</td>
                        <td>{{ row.approver || '-' }}</td>
                        <td>
                            <a href="javascript:void(0)" @click="handleEdit(row)">编辑</a>
                            &nbsp;|&nbsp;
                            <a href="javascript:void(0)" class="danger" @click="handleDelete(row)">删除</a>
                            &nbsp;|&nbsp;
                            <a href="javascript:void(0)" @click="handleView(row)">查看</a>
                            &nbsp;|&nbsp;
                            <a href="javascript:void(0)" @click="handleSubmit?.(row)">提交审批</a>
                        </td>
                    </tr>
                </tbody>
            </table>
        </div>

        <!-- 分页（数字页码 + 跳转） -->
        <div class="pagination advanced" v-if="total > 0">
            <span class="sum">共{{ totalPage }}页/{{ total }}条数据</span>
            <button class="nav" :disabled="page === 1" @click="goto(page - 1)">‹</button>
            <button v-for="p in pagesToShow" :key="p.key" class="num"
                :class="{ active: p.page === page, ellipsis: p.ellipsis }" :disabled="p.ellipsis"
                @click="!p.ellipsis && goto(p.page)">
                {{ p.label }}
            </button>
            <button class="nav" :disabled="page >= totalPage" @click="goto(page + 1)">›</button>
            <span class="jump">跳至</span>
            <input class="jump-input" type="number" min="1" :max="Math.max(totalPage, 1)" v-model.number="jumpPage"
                @keyup.enter="jump()" />
            <span class="jump">页</span>
        </div>

        <!-- 详情弹窗 -->
        <div class="dialog-mask" v-if="showDetail" @click.self="closeDetail">
            <div class="dialog">
                <h3>合同详情</h3>
                <div v-if="detailLoading">加载中...</div>
                <div v-else>
                    <p><b>合同编号：</b>{{ detail.contractNumber || '-' }}</p>
                    <p><b>合同标题：</b>{{ detail.contractTitle || '-' }}</p>
                    <p><b>货主单位：</b>{{ detail.cargoOwnerUnit || detail.partnerUnit || '-' }}</p>
                    <p><b>货主负责人：</b>{{ detail.cargoOwnerContact || '-' }}</p>
                    <p><b>线路：</b>{{ detail.route || '-' }}</p>
                    <p><b>吨运价：</b>{{ detail.tonFreightRate }}</p>
                    <p><b>包车条件吨位：</b>{{ detail.charterConditionTonnage }}</p>
                    <p><b>包车金额：</b>{{ detail.charterAmount }}</p>
                    <p><b>合同金额：</b>{{ detail.contractAmount || '-' }}</p>
                    <p><b>签订日期：</b>{{ detail.signingDate }}</p>
                    <p><b>经办人：</b>{{ detail.handler || '-' }}</p>
                    <p><b>创建时间：</b>{{ detail.createdAt }}</p>
                    <p><b>状态：</b>{{ detail.status || '-' }}</p>
                    <p><b>审批人：</b>{{ detail.approver || '-' }}</p>
                    <p v-if="detail.contractSubjectDescription"><b>合同标的/项目说明：</b><br />{{
                        detail.contractSubjectDescription }}</p>
                    <p v-if="detail.contractTerms"><b>主要条款/变更条款：</b><br />{{ detail.contractTerms }}</p>
                    <p v-if="detail.attachments && detail.attachments.length"><b>附件：</b>
                        <span v-for="(a, i) in detail.attachments" :key="i">
                            <a :href="a" target="_blank">{{ getFileName(a) }}</a><span
                                v-if="i < detail.attachments.length - 1">, </span>
                        </span>
                    </p>
                </div>
                <div class="dialog-footer">
                    <button class="btn" @click="closeDetail">关闭</button>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, computed } from 'vue'
import { useRouter } from 'vue-router'
import { read, write } from '@/assets/Axios/axiosHttple'
const router = useRouter()

// 提交式查询输入与实际查询条件
const inputFilters = reactive({
    contractTitle: '',
    cargoOwnerUnit: '',
    handler: '',
    signingStart: '',
    signingEnd: '',
    status: ''
})
const filters = reactive({
    contractTitle: '',
    cargoOwnerUnit: '',
    handler: '',
    signingStart: '',
    signingEnd: '',
    status: ''
})

const page = ref(1)
const pageSize = ref(10)
const total = ref(0)
const totalPage = ref(0)
const loading = ref(false)
const rows = ref<any[]>([])
const jumpPage = ref<number | null>(1)

const selectedIds = ref<number[]>([])
const allSelected = ref(false)

function toggleOne(id: number) {
    if (selectedIds.value.includes(id)) {
        selectedIds.value = selectedIds.value.filter(x => x !== id)
    } else {
        selectedIds.value.push(id)
    }
    allSelected.value = rows.value.length > 0 && selectedIds.value.length === rows.value.length
}
function toggleAll(e: Event) {
    const checked = (e.target as HTMLInputElement).checked
    allSelected.value = checked
    selectedIds.value = checked ? rows.value.map(r => r.id) : []
}

function handleCreate() {
    router.push('/AddCargoOwnerContracts')
}

async function handleDelete(row: any) {
    if (!row || !row.id) { alert('缺少要删除的记录'); return }
    if (!confirm('确定删除该条记录？此操作不可恢复。')) return

    const idNum = Number(row.id)
    const idEnc = encodeURIComponent(String(row.id))
    const deletedBy = String(localStorage.getItem('userId') ?? localStorage.getItem('UserId') ?? '')

    // 统一走 8000 写网关，按候选路径依次尝试
    const candidates: Array<{ url: string; body: any }> = [
        { url: `contractmanagementwrite/api/ContractManagement/DeleteCargoOwner/cargo/delete/${idEnc}`, body: { deletedBy } },
        { url: `contractmanagementwrite/api/ContractManagement/Delete/delete/${idEnc}`, body: { deletedBy } },
        { url: `contractmanagementwrite/api/ContractManagement/DeleteCargoOwner/cargo/delete`, body: { id: idNum, deletedBy } },
        { url: `contractmanagementwrite/api/ContractManagement/Delete/delete`, body: { id: idNum, deletedBy } }
    ]

    let lastError: any = null
    for (const c of candidates) {
        try {
            const res = await write.post(c.url, c.body)
            const data = res?.data ?? {}
            if (res.status === 200 && (Number(data?.code) === 200 || data?.data === true || typeof data?.data === 'number' || data?.success === true)) {
                alert('删除成功')
                fetchList()
                return
            }
            lastError = { status: res?.status, body: data }
        } catch (e) {
            lastError = e
        }
    }
    alert(`删除失败：${lastError?.body?.message || lastError?.message || ''}`)
}

async function handleBatchDelete() {
    if (selectedIds.value.length === 0) { alert('请选择要删除的记录'); return }
    if (!confirm(`确认删除选中的 ${selectedIds.value.length} 条记录？此操作不可恢复。`)) return

    const ids = selectedIds.value.slice()
    const deletedBy = String(localStorage.getItem('userId') ?? localStorage.getItem('UserId') ?? '')

    const candidates: Array<{ url: string; body: any }> = [
        { url: 'contractmanagementwrite/api/ContractManagement/DeleteRangeCargoOwner/cargo/delete/batch', body: { ids, deletedBy } },
        { url: 'contractmanagementwrite/api/ContractManagement/DeleteRange/delete/batch', body: { ids, deletedBy } }
    ]

    let lastError: any = null
    for (const c of candidates) {
        try {
            const res = await write.post(c.url, c.body)
            const data = res?.data ?? {}
            if (res.status === 200 && (Number(data?.code) === 200 || data?.data === true || typeof data?.data === 'number' || data?.success === true)) {
                alert('批量删除成功')
                selectedIds.value = []
                allSelected.value = false
                page.value = 1
                fetchList()
                return
            }
            lastError = { status: res?.status, body: data }
        } catch (e) {
            lastError = e
        }
    }
    alert(`批量删除失败：${lastError?.body?.message || lastError?.message || ''}`)
}

function handleEdit(row: any) {
    router.push(`/UpdateCargoOwnerContracts?id=${encodeURIComponent(row.id)}`)
}

const showDetail = ref(false)
const detailLoading = ref(false)
const detail = ref<any>({})

function closeDetail() { showDetail.value = false }

async function handleView(row: any) {
    showDetail.value = true
    detailLoading.value = true
    try {
        // 先复制行数据作为基础详情
        const det: any = { ...row }

        // 若货主负责人字段是数字 ID，则尝试通过货主管理接口查询姓名（走 8000 网关）
        try {
            const possibleOwnerId = Number(row.cargoOwnerContact ?? row.OwnerId ?? row.ownerId ?? row.Owner ?? row.owner)
            if (Number.isFinite(possibleOwnerId) && possibleOwnerId > 0) {
                try {
                    const r1 = await read.get(`contractmanagementread/api/CargoOwner/GetCargoOwnerById/${encodeURIComponent(String(possibleOwnerId))}`)
                    const d = r1?.data?.data ?? r1?.data
                    if (d) {
                        det.cargoOwnerContact = d.OwnerName ?? d.ownerName ?? d.Contact ?? d.contact ?? det.cargoOwnerContact
                    }
                } catch {
                    const r2 = await read.get('contractmanagementread/api/CargoOwner/GetCargoOwnerById', { params: { id: possibleOwnerId } })
                    const d2 = r2?.data?.data ?? r2?.data
                    if (d2) {
                        det.cargoOwnerContact = d2.OwnerName ?? d2.ownerName ?? d2.Contact ?? d2.contact ?? det.cargoOwnerContact
                    }
                }
            }
        } catch (e) {
            // ignore owner lookup errors
        }

        // 若路线为空且存在线路ID，尝试通过线路接口映射名称
        try {
            if ((!det.route || String(det.route).trim() === '') && (row.RouteId || row.routeId || row.RouteInfoId || row.routeInfoId || row.unitId)) {
                const res = await read.get('contractmanagementread/api/ContractManagementControllers/Route', {
                    params: { PageIndex: 1, PageSize: 999, t: Date.now() }
                })
                if (res && res.status === 200) {
                    const j: any = res.data ?? {}
                    const block = j?.data || j
                    const rlist = Array.isArray(block?.data) ? block.data : (Array.isArray(block) ? block : [])
                    const rid = Number(row.RouteId ?? row.routeId ?? row.RouteInfoId ?? row.routeInfoId)
                    if (Number.isFinite(rid) && rid > 0) {
                        const found = rlist.find((r: any) => Number(r.Id ?? r.id ?? r.RouteId ?? r.routeId) === rid)
                        if (found) det.route = found.RouteName ?? found.routeName ?? found.Name ?? found.name ?? det.route
                    }
                }
            }
        } catch (e) {
            // ignore route lookup errors
        }

        detail.value = det
    } finally {
        detailLoading.value = false
    }
}

// 提交审批：本地直接成功并更新状态与审批人
async function handleSubmit(row: any) {
    try {
        if (row) {
            row.status = '待审核'
            row.approver = '王总'
            const idx = rows.value.findIndex(r => r.id === row.id)
            if (idx >= 0) {
                rows.value[idx] = { ...rows.value[idx], status: row.status, approver: row.approver }
            }
        }
    } finally {
        alert('提交成功')
    }
}

function handleSearch() {
    filters.contractTitle = inputFilters.contractTitle.trim()
    filters.cargoOwnerUnit = inputFilters.cargoOwnerUnit.trim()
    filters.handler = inputFilters.handler.trim()
    filters.signingStart = inputFilters.signingStart
    filters.signingEnd = inputFilters.signingEnd
    filters.status = inputFilters.status
    page.value = 1
    fetchList()
}

function handleReset() {
    inputFilters.contractTitle = ''
    inputFilters.cargoOwnerUnit = ''
    inputFilters.handler = ''
    inputFilters.signingStart = ''
    inputFilters.signingEnd = ''
    inputFilters.status = ''
    filters.contractTitle = ''
    filters.cargoOwnerUnit = ''
    filters.handler = ''
    filters.signingStart = ''
    filters.signingEnd = ''
    filters.status = ''
    page.value = 1
    fetchList()
}

function goto(p: number) {
    if (p < 1 || (totalPage.value && p > totalPage.value)) return
    page.value = p
    fetchList()
}

function jump() {
    if (!jumpPage.value) return
    const p = Math.max(1, Math.min(Number(jumpPage.value), Math.max(totalPage.value, 1)))
    goto(p)
}

const pagesToShow = computed(() => {
    const maxPage = Math.max(totalPage.value, 1)
    const current = Math.min(Math.max(page.value, 1), maxPage)
    const pages: { key: string; page: number; label: string; ellipsis?: boolean }[] = []
    const pushPage = (p: number) => pages.push({ key: `p-${p}`, page: p, label: String(p) })
    const pushEllipsis = (i: number) => pages.push({ key: `e-${i}`, page: -1, label: '...', ellipsis: true })

    if (maxPage <= 7) {
        for (let i = 1; i <= maxPage; i++) pushPage(i)
        return pages
    }
    pushPage(1)
    if (current > 4) pushEllipsis(1)
    const start = Math.max(2, current - 1)
    const end = Math.min(maxPage - 1, current + 1)
    for (let i = start; i <= end; i++) pushPage(i)
    if (current < maxPage - 3) pushEllipsis(2)
    pushPage(maxPage)
    return pages
})

// 从 URL 或 fileName 中提取文件名
function getFileName(url: string) {
    try {
        const u = new URL(url)
        const p = u.pathname || ''
        const segs = p.split('/')
        const last = segs[segs.length - 1] || url
        return decodeURIComponent(last)
    } catch {
        const segs = String(url).split(/[\\/\\\\]/)
        return segs[segs.length - 1] || String(url)
    }
}

function normalizeDateString(val: any) {
    if (!val) return ''
    try {
        const d = new Date(val)
        if (isNaN(d.getTime())) return ''
        return d.toISOString().slice(0, 10)
    } catch { return '' }
}

async function fetchList() {
    loading.value = true
    try {
        const params = new URLSearchParams()
        params.append('PageIndex', String(page.value))
        params.append('PageSize', String(pageSize.value))
        // 查询字段映射（尝试多种后端命名）
        if (filters.contractTitle) { params.append('contractTitle', filters.contractTitle); params.append('ContractTitle', filters.contractTitle) }
        if (filters.cargoOwnerUnit) { params.append('cargoOwnerUnit', filters.cargoOwnerUnit); params.append('CargoOwnerUnit', filters.cargoOwnerUnit) }
        if (filters.handler) { params.append('handler', filters.handler); params.append('Handler', filters.handler) }
        if (filters.status) { params.append('status', filters.status); params.append('Status', filters.status) }
        if (filters.signingStart) { params.append('signingStart', filters.signingStart); params.append('SigningStart', filters.signingStart) }
        if (filters.signingEnd) { params.append('signingEnd', filters.signingEnd); params.append('SigningEnd', filters.signingEnd) }
        params.append('t', String(Date.now()))

        const res = await read.get('contractmanagementread/api/ContractManagementControllers/GetCargoOwnerContracts/CargoOwner', { params })
        let data: any = res?.data ?? {}

        const listContainer = data?.data || {}
        total.value = Number(listContainer?.TotalCount || 0)
        totalPage.value = Number(listContainer?.TotalPage || 0)
        const arr = Array.isArray(listContainer?.data) ? listContainer.data : []

        // 尝试批量获取货主列表以便将负责人 ID 映射为姓名
        const ownerMap = new Map<number, string>()
        try {
            const resOwners = await read.get('contractmanagementread/api/CargoOwner/GetCargoOwnerList', { params: { PageIndex: 1, PageSize: 999 } })
            const block = resOwners?.data?.data ?? resOwners?.data
            const clist = Array.isArray(block) ? block : (Array.isArray(block?.data) ? block.data : [])
            for (const c of clist) {
                const id = Number(c.OwnerId ?? c.ownerId ?? c.Id ?? c.id)
                const name = c.ownerName ?? c.OwnerName ?? c.Contact ?? c.contact ?? c.Principal ?? c.principal ?? c.Name ?? c.name
                if (Number.isFinite(id) && name) ownerMap.set(id, String(name))
            }
        } catch (e) {
            // ignore
        }

        rows.value = arr.map((it: any) => ({
            id: it.Id,
            contractNumber: it.ContractNumber,
            contractTitle: it.ContractTitle,
            cargoOwnerUnit: it.CargoOwnerUnit ?? it.UnitId ?? '',
            // 负责人：优先使用直接返回的名称字段；如果为数字或缺失，尝试用 ownerMap 映射
            cargoOwnerContact: (() => {
                const raw = it.CargoOwnerContact ?? it.OwnerName ?? it.ownerName ?? ''
                if (raw === null || raw === undefined || String(raw).trim() === '') {
                    const oid = Number(it.OwnerId ?? it.ownerId ?? it.Owner ?? it.owner)
                    if (!Number.isNaN(oid) && ownerMap.has(oid)) return ownerMap.get(oid)
                    return ''
                }
                // 如果 raw 是数字字符串或数字，尝试映射
                const num = Number(raw)
                if (!Number.isNaN(num) && ownerMap.has(num)) return ownerMap.get(num)
                return String(raw)
            })(),
            route: it.Route,
            // 附件兼容多种字段名：fileUrl / filePath / contractAttachment
            attachment: it?.fileUrl ?? it?.filePath ?? it?.contractAttachment ?? it?.ContractAttachment ?? '',
            tonFreightRate: it.TonFreightRate,
            charterConditionTonnage: it.CharterConditionTonnage,
            charterAmount: it.CharterAmount,
            signingDate: normalizeDateString(it.SigningDate),
            handler: it.Handler,
            contractAmount: it.ContractAmount,
            createdAt: normalizeDateString(it.CreatedAt),
            status: it.Status,
            approver: it.Approver
        }))
    } catch (e) {
        console.error(e)
        rows.value = []
        total.value = 0
        totalPage.value = 0
    } finally {
        loading.value = false
    }
}

onMounted(() => {
    // 初次进入或 ?refresh=1 后刷新
    const url = new URL(window.location.href)
    if (url.searchParams.get('refresh') === '1') {
        url.searchParams.delete('refresh')
        history.replaceState(null, '', `${url.pathname}${url.search}`)
    }
    fetchList()
})
</script>

<style scoped>
.page {
    padding: 16px;
}

.title {
    margin: 8px 0 12px;
    font-size: 18px;
}

.search {
    background: #f7f7f7;
    padding: 12px;
    border-radius: 6px;
    margin-bottom: 12px;
}

.row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-bottom: 8px;
    flex-wrap: wrap;
}

.row label {
    color: #333;
}

input,
select {
    height: 30px;
    padding: 0 8px;
    border: 1px solid #ddd;
    border-radius: 4px;
}

.btn {
    height: 30px;
    padding: 0 12px;
    border: 1px solid #ddd;
    background: #fff;
    border-radius: 4px;
    cursor: pointer;
}

.btn.primary {
    background: #1677ff;
    color: #fff;
    border-color: #1677ff;
}

.btn.danger {
    background: #ff4d4f;
    color: #fff;
    border-color: #ff4d4f;
}

.toolbar {
    display: flex;
    gap: 8px;
    margin: 8px 0;
}

.table {
    width: 100%;
    border-collapse: collapse;
    background: #fff;
}

.table th,
.table td {
    border: 1px solid #eee;
    padding: 8px;
    text-align: left;
}

.table thead {
    background: #fafafa;
}

.table a {
    color: #1677ff;
    text-decoration: none;
}

.table a.danger {
    color: #ff4d4f;
}

.table-wrapper {
    overflow: auto;
}

.pagination {
    display: flex;
    gap: 12px;
    align-items: center;
    justify-content: center;
    padding: 12px 0;
}

.pagination.advanced {
    gap: 6px;
}

.pagination .num {
    min-width: 32px;
    height: 28px;
    border: 1px solid #ddd;
    background: #fff;
    border-radius: 4px;
    cursor: pointer;
}

.pagination .num.active {
    background: #13c2c2;
    color: #fff;
    border-color: #13c2c2;
}

.pagination .num.ellipsis {
    cursor: default;
    padding: 0 8px;
}

.pagination .nav {
    min-width: 32px;
    height: 28px;
    border: 1px solid #ddd;
    background: #fff;
    border-radius: 4px;
    cursor: pointer;
}

.pagination .sum {
    color: #666;
    margin-right: 6px;
}

.pagination .jump {
    color: #666;
}

.pagination .jump-input {
    width: 56px;
    height: 28px;
    padding: 0 6px;
    border: 1px solid #ddd;
    border-radius: 4px;
}

.dialog-mask {
    position: fixed;
    inset: 0;
    background: rgba(0, 0, 0, 0.35);
    display: flex;
    align-items: center;
    justify-content: center;
}

.dialog {
    width: 520px;
    max-width: 90vw;
    background: #fff;
    border-radius: 8px;
    padding: 16px;
}

.dialog-footer {
    display: flex;
    justify-content: flex-end;
    margin-top: 12px;
}
</style>
